﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.IO;

using MEFedMVVM.ViewModelLocator;
using Cinch;
using System.Configuration;
using System.Threading;
using System.Data.Objects.DataClasses;

namespace Anata.Client
{

    /// <summary>
    /// Runtime implementation of the 
    /// Data service used by the <c>ImageLoaderViewModel</c> to obtain data
    /// </summary>
    [PartCreationPolicy(CreationPolicy.NonShared)]
    [ExportService(ServiceType.Runtime, typeof(IReferenceProvider))]
    public class ReferenceProvider : IReferenceProvider
    {
        #region Data
        private BackgroundTaskManager<int, List<Konsumen>> multiFetchBgWorkerKonsumen =
            new BackgroundTaskManager<int, List<Konsumen>>();
        private BackgroundTaskManager<int, List<CabangLayanan>> multiFetchBgWorkerCabangLayanan =
            new BackgroundTaskManager<int, List<CabangLayanan>>();
        private BackgroundTaskManager<int, List<CabangProduk>> multiFetchBgWorkerCabangProduk =
            new BackgroundTaskManager<int, List<CabangProduk>>();
        private BackgroundTaskManager<int, List<Karyawan>> multiFetchBgWorkerKaryawan =
            new BackgroundTaskManager<int, List<Karyawan>>();
        private BackgroundTaskManager<int, List<FreeGift>> multiFetchBgWorkerFreeGift =
            new BackgroundTaskManager<int, List<FreeGift>>();
        private BackgroundTaskManager<int, List<Promo>> multiFetchBgWorkerPromo =
            new BackgroundTaskManager<int, List<Promo>>();
        private BackgroundTaskManager<int, List<JenisPembayaran>> multiFetchBgWorkerJenisPembayaran =
            new BackgroundTaskManager<int, List<JenisPembayaran>>();



        //baru
        private BackgroundTaskManager<int, List<KonsumenThumbnailViewModel>> multiFetchKonsumenTVMBgWorker =
            new BackgroundTaskManager<int, List<KonsumenThumbnailViewModel>>();
        private BackgroundTaskManager<int, List<CabangLayananThumbnailViewModel>> multiFetchCabangLayananTVMBgWorker =
            new BackgroundTaskManager<int, List<CabangLayananThumbnailViewModel>>();
        private BackgroundTaskManager<int, List<CabangProdukThumbnailViewModel>> multiFetchCabangProdukTVMBgWorker =
            new BackgroundTaskManager<int, List<CabangProdukThumbnailViewModel>>();
        //private BackgroundTaskManager<int, List<KaryawanLayananThumbnailViewModel>> multiFetchCabangProdukTVMBgWorker =
        //    new BackgroundTaskManager<int, List<KaryawanLayananThumbnailViewModel>>();
        private BackgroundTaskManager<int, List<KaryawanThumbnailViewModel>> multiFetchKaryawanTVMBgWorker =
            new BackgroundTaskManager<int, List<KaryawanThumbnailViewModel>>();
        private BackgroundTaskManager<int, List<FreeGiftThumbnailViewModel>> multiFetchFreeGiftTVMBgWorker =
            new BackgroundTaskManager<int, List<FreeGiftThumbnailViewModel>>();
        private BackgroundTaskManager<int, List<PromoThumbnailViewModel>> multiFetchPromoTVMBgWorker =
            new BackgroundTaskManager<int, List<PromoThumbnailViewModel>>();
        //private BackgroundTaskManager<int, List<JenisPembayaranThumbnailViewModel>> multiFetchBgWorkerJenisPembayaran =
        //    new BackgroundTaskManager<int, List<JenisPembayaranThumbnailViewModel>>();
        private BackgroundTaskManager<int, List<LayananThumbnailViewModel>> multiFetchLayananTVMBgWorker =
            new BackgroundTaskManager<int, List<LayananThumbnailViewModel>>();

        //lebih baru lagi
        private BackgroundTaskManager<int, List<JenisKelamin>> multiFetchJenisKelaminBgWorker =
            new BackgroundTaskManager<int, List<JenisKelamin>>();
        private BackgroundTaskManager<int, List<Status>> multiFetchStatusBgWorker =
            new BackgroundTaskManager<int, List<Status>>();
        private BackgroundTaskManager<int, List<Agama>> multiFetchAgamaBgWorker =
            new BackgroundTaskManager<int, List<Agama>>();
        private BackgroundTaskManager<int, List<GolonganDarah>> multiFetchGolonganDarahBgWorker =
            new BackgroundTaskManager<int, List<GolonganDarah>>();

        private BackgroundTaskManager<int, List<SimpleLayananViewModel>> multiFetchLayananSVMBgWorker =
            new BackgroundTaskManager<int, List<SimpleLayananViewModel>>();
        private BackgroundTaskManager<int, List<SimpleKategoriStokViewModel>> multiFetchKategoriStokSVMBgWorker =
            new BackgroundTaskManager<int, List<SimpleKategoriStokViewModel>>();
        private BackgroundTaskManager<int, List<SimpleJenisStokViewModel>> multiFetchJenisStokSVMBgWorker =
            new BackgroundTaskManager<int, List<SimpleJenisStokViewModel>>();
        private BackgroundTaskManager<int, List<SimpleRekeningViewModel>> multiFetchRekeningSVMBgWorker =
            new BackgroundTaskManager<int, List<SimpleRekeningViewModel>>();
        private BackgroundTaskManager<int, List<SimpleJenisAsetViewModel>> multiFetchJenisAsetSVMBgWorker =
            new BackgroundTaskManager<int, List<SimpleJenisAsetViewModel>>();
        private BackgroundTaskManager<int, List<SimpleJenisMutasiStokViewModel>> multiFetchJenisMutasiStokSVMBgWorker =
            new BackgroundTaskManager<int, List<SimpleJenisMutasiStokViewModel>>();
        private BackgroundTaskManager<int, List<SimpleJenisMutasiRekeningViewModel>> multiFetchJenisMutasiRekeningSVMBgWorker =
            new BackgroundTaskManager<int, List<SimpleJenisMutasiRekeningViewModel>>();
        #endregion

        #region PublicMethods
        public void LazyFetchKonsumens(int page, Action<List<Konsumen>> callback)
        {
            BackgroundTaskManager<int, List<Konsumen>> bgWorker = null;
            if (multiFetchBgWorkerKonsumen.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<Konsumen>>();
            }
            else
            {
                bgWorker = multiFetchBgWorkerKonsumen;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return FetchKonsumensInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchCabangLayanans(int page, Action<List<CabangLayanan>> callback)
        {
            BackgroundTaskManager<int, List<CabangLayanan>> bgWorker = null;
            if (multiFetchBgWorkerCabangLayanan.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<CabangLayanan>>();
            }
            else
            {
                bgWorker = multiFetchBgWorkerCabangLayanan;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return FetchCabangLayanansInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchCabangProduks(int page, Action<List<CabangProduk>> callback)
        {
            BackgroundTaskManager<int, List<CabangProduk>> bgWorker = null;
            if (multiFetchBgWorkerCabangProduk.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<CabangProduk>>();
            }
            else
            {
                bgWorker = multiFetchBgWorkerCabangProduk;
            }

            bgWorker.TaskFunc = (argument) =>
                {
                    return FetchCabangProduksInternal(argument);
                };

            bgWorker.CompletionAction = (result) =>
                {
                    callback(result);
                };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();

        }
        public void LazyFetchKaryawans(int page, Action<List<Karyawan>> callback)
        {
            BackgroundTaskManager<int, List<Karyawan>> bgWorker = null;
            if (multiFetchBgWorkerKaryawan.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<Karyawan>>();
            }
            else
            {
                bgWorker = multiFetchBgWorkerKaryawan;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return FetchKaryawansInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchFreeGifts(int page, Action<List<FreeGift>> callback)
        {
            BackgroundTaskManager<int, List<FreeGift>> bgWorker = null;
            if (multiFetchBgWorkerFreeGift.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<FreeGift>>();
            }
            else
            {
                bgWorker = multiFetchBgWorkerFreeGift;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return FetchFreeGiftsInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchPromos(int page, Action<List<Promo>> callback)
        {
            BackgroundTaskManager<int, List<Promo>> bgWorker = null;
            if (multiFetchBgWorkerPromo.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<Promo>>();
            }
            else
            {
                bgWorker = multiFetchBgWorkerPromo;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return FetchPromosInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchJenisPembayarans(int page, Action<List<JenisPembayaran>> callback)
        {
            BackgroundTaskManager<int, List<JenisPembayaran>> bgWorker = null;
            if (multiFetchBgWorkerJenisPembayaran.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<JenisPembayaran>>();
            }
            else
            {
                bgWorker = multiFetchBgWorkerJenisPembayaran;
            }
            bgWorker.TaskFunc = (argument) =>
                {
                    return FetchJenisPembayaransInternal(argument);
                };

            bgWorker.CompletionAction = (result) =>
                {
                    callback(result);
                };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        
        
        
        //baru
        public void LazyFetchKonsumens(int page, Action<List<KonsumenThumbnailViewModel>> callback) 
        {
            BackgroundTaskManager<int, List<KonsumenThumbnailViewModel>> bgWorker = null;
            if (multiFetchKonsumenTVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<KonsumenThumbnailViewModel>>();
            }
            else
            {
                bgWorker = multiFetchKonsumenTVMBgWorker;
            }
            bgWorker.TaskFunc = (argument) =>
            {
                return FetchKonsumenTVMsInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchCabangLayanans(int page, Action<List<CabangLayananThumbnailViewModel>> callback)
        {
            BackgroundTaskManager<int, List<CabangLayananThumbnailViewModel>> bgWorker = null;
            if (multiFetchCabangLayananTVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<CabangLayananThumbnailViewModel>>();
            }
            else
            {
                bgWorker = multiFetchCabangLayananTVMBgWorker;
            }
            bgWorker.TaskFunc = (argument) =>
            {
                return FetchCabangLayananTVMsInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchCabangProduks(int page, Action<List<CabangProdukThumbnailViewModel>> callback)
        {
            BackgroundTaskManager<int, List<CabangProdukThumbnailViewModel>> bgWorker = null;
            if (multiFetchCabangProdukTVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<CabangProdukThumbnailViewModel>>();
            }
            else
            {
                bgWorker = multiFetchCabangProdukTVMBgWorker;
            }
            bgWorker.TaskFunc = (argument) =>
            {
                return FetchCabangProdukTVMsInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchKaryawans(int page, Action<List<KaryawanThumbnailViewModel>> callback)
        {
            BackgroundTaskManager<int, List<KaryawanThumbnailViewModel>> bgWorker = null;
            if (multiFetchKaryawanTVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<KaryawanThumbnailViewModel>>();
            }
            else
            {
                bgWorker = multiFetchKaryawanTVMBgWorker;
            }
            bgWorker.TaskFunc = (argument) =>
            {
                return FetchKaryawanTVMsInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchFreeGifts(int page, Action<List<FreeGiftThumbnailViewModel>> callback)
        {
            BackgroundTaskManager<int, List<FreeGiftThumbnailViewModel>> bgWorker = null;
            if (multiFetchFreeGiftTVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<FreeGiftThumbnailViewModel>>();
            }
            else
            {
                bgWorker = multiFetchFreeGiftTVMBgWorker;
            }
            bgWorker.TaskFunc = (argument) =>
            {
                return FetchFreeGiftTVMsInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchPromos(int page, Action<List<PromoThumbnailViewModel>> callback)
        {
            BackgroundTaskManager<int, List<PromoThumbnailViewModel>> bgWorker = null;
            if (multiFetchPromoTVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<PromoThumbnailViewModel>>();
            }
            else
            {
                bgWorker = multiFetchPromoTVMBgWorker;
            }
            bgWorker.TaskFunc = (argument) =>
            {
                return FetchPromoTVMsInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }

        public void LazyFetchLayanans(int page, Action<List<LayananThumbnailViewModel>> callback)
        {
            BackgroundTaskManager<int, List<LayananThumbnailViewModel>> bgWorker = null;
            if (multiFetchLayananTVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<LayananThumbnailViewModel>>();
            }
            else
            {
                bgWorker = multiFetchLayananTVMBgWorker;
            }
            bgWorker.TaskFunc = (argument) =>
            {
                return FetchLayananTVMsInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyFetchCabangs(int page, Action<List<CabangThumbnailViewModel>> callback) { }
        public void LazyFetchJenisStoks(int page, Action<List<JenisStokThumbnailViewModel>> callback) { }



        //lebih baru
        public void LazyFetchJenisKelamins(int page, Action<List<JenisKelamin>> callback) 
        {
            multiFetchJenisKelaminBgWorker.TaskFunc = (argument) =>
            {
                return FetchJenisKelaminsInternal(argument);
            };

            multiFetchJenisKelaminBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchJenisKelaminBgWorker.WorkerArgument = page;
            multiFetchJenisKelaminBgWorker.RunBackgroundTask();
        }
        public void LazyFetchStatuss(int page, Action<List<Status>> callback)
        {
            multiFetchStatusBgWorker.TaskFunc = (argument) =>
            {
                return FetchStatussInternal(argument);
            };

            multiFetchStatusBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchStatusBgWorker.WorkerArgument = page;
            multiFetchStatusBgWorker.RunBackgroundTask();
        }
        public void LazyFetchAgamas(int page, Action<List<Agama>> callback)
        {
            multiFetchAgamaBgWorker.TaskFunc = (argument) =>
            {
                return FetchAgamasInternal(argument);
            };

            multiFetchAgamaBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchAgamaBgWorker.WorkerArgument = page;
            multiFetchAgamaBgWorker.RunBackgroundTask();
        }
        public void LazyFetchGolonganDarahs(int page, Action<List<GolonganDarah>> callback)
        {
            multiFetchGolonganDarahBgWorker.TaskFunc = (argument) =>
            {
                return FetchGolonganDarahsInternal(argument);
            };

            multiFetchGolonganDarahBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchGolonganDarahBgWorker.WorkerArgument = page;
            multiFetchGolonganDarahBgWorker.RunBackgroundTask();
        }

        public void LazyFetchLayanans(int page, Action<List<SimpleLayananViewModel>> callback)
        {
            multiFetchLayananSVMBgWorker.TaskFunc = (argument) =>
            {
                return FetchLayananSVMsInternal(argument);
            };

            multiFetchLayananSVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchLayananSVMBgWorker.WorkerArgument = page;
            multiFetchLayananSVMBgWorker.RunBackgroundTask();
        }
        public void LazyFetchKategoriStoks(int page, Action<List<SimpleKategoriStokViewModel>> callback)
        {
            multiFetchKategoriStokSVMBgWorker.TaskFunc = (argument) =>
            {
                return FetchKategoriStokSVMsInternal(argument);
            };

            multiFetchKategoriStokSVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchKategoriStokSVMBgWorker.WorkerArgument = page;
            multiFetchKategoriStokSVMBgWorker.RunBackgroundTask();
        }
        public void LazyFetchJenisStoks(int page, Action<List<SimpleJenisStokViewModel>> callback)
        {
            multiFetchJenisStokSVMBgWorker.TaskFunc = (argument) =>
            {
                return FetchJenisStokSVMsInternal(argument);
            };

            multiFetchJenisStokSVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchJenisStokSVMBgWorker.WorkerArgument = page;
            multiFetchJenisStokSVMBgWorker.RunBackgroundTask();
        }
        public void LazyFetchRekenings(int page, Action<List<SimpleRekeningViewModel>> callback)
        {
            multiFetchRekeningSVMBgWorker.TaskFunc = (argument) =>
            {
                return FetchRekeningSVMsInternal(argument);
            };

            multiFetchRekeningSVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchRekeningSVMBgWorker.WorkerArgument = page;
            multiFetchRekeningSVMBgWorker.RunBackgroundTask();
        }
        public void LazyFetchJenisAsets(int page, Action<List<SimpleJenisAsetViewModel>> callback)
        {
            multiFetchJenisAsetSVMBgWorker.TaskFunc = (argument) =>
            {
                return FetchJenisAsetSVMsInternal(argument);
            };

            multiFetchJenisAsetSVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchJenisAsetSVMBgWorker.WorkerArgument = page;
            multiFetchJenisAsetSVMBgWorker.RunBackgroundTask();
        }
        public void LazyFetchJenisMutasiStoks(int page, Action<List<SimpleJenisMutasiStokViewModel>> callback)
        {
            multiFetchJenisMutasiStokSVMBgWorker.TaskFunc = (argument) =>
            {
                return FetchJenisMutasiStokSVMsInternal(argument);
            };

            multiFetchJenisMutasiStokSVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchJenisMutasiStokSVMBgWorker.WorkerArgument = page;
            multiFetchJenisMutasiStokSVMBgWorker.RunBackgroundTask();
        }
        public void LazyFetchJenisMutasiRekenings(int page, Action<List<SimpleJenisMutasiRekeningViewModel>> callback)
        {
            multiFetchJenisMutasiRekeningSVMBgWorker.TaskFunc = (argument) =>
            {
                return FetchJenisMutasiRekeningSVMsInternal(argument);
            };

            multiFetchJenisMutasiRekeningSVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchJenisMutasiRekeningSVMBgWorker.WorkerArgument = page;
            multiFetchJenisMutasiRekeningSVMBgWorker.RunBackgroundTask();
        }
        #endregion

        #region PublicProperties
        /// <summary>
        /// To allow this class to be unit tested stand alone
        /// See CinchV1 articles about Unit Testing for this
        /// Or comments in Cinch BackgroundTaskManager<T> class
        /// </summary>
        public BackgroundTaskManager<int, List<CabangLayanan>> MultiFetchBgWorkerCabangLayanan
        {
            get { return multiFetchBgWorkerCabangLayanan; }
        }
        public BackgroundTaskManager<int, List<CabangProduk>> MultiFetchBgWorkerCabangProduk
        {
            get { return multiFetchBgWorkerCabangProduk; }
        }
        public BackgroundTaskManager<int, List<Karyawan>> MultiFetchBgWorkerKaryawan
        {
            get { return multiFetchBgWorkerKaryawan; }
        }
        public BackgroundTaskManager<int, List<FreeGift>> MultiFetchBgWorkerFreeGift
        {
            get { return multiFetchBgWorkerFreeGift; }
        }
        public BackgroundTaskManager<int, List<Promo>> MultiFetchBgWorkerPromo
        {
            get { return multiFetchBgWorkerPromo; }
        }
        public BackgroundTaskManager<int, List<JenisPembayaran>> MultiFetchBgWorkerJenisPembayaran
        {
            get { return multiFetchBgWorkerJenisPembayaran; }
        }

        #endregion

        #region PrivateMethods
        private List<Konsumen> FetchKonsumensInternal(int page)
        {
            List<Konsumen> konsumens = new List<Konsumen>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                using (AnataEntities context = new AnataEntities())
                {
                    IQueryable<Konsumen> konsumenQuery =
                        from konsumen in context.Konsumen
                        orderby konsumen.Nama
                        select konsumen;
                    konsumens = konsumenQuery.Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) {}
            return konsumens;
        }
        private List<CabangLayanan> FetchCabangLayanansInternal(int page)
        {
            List<CabangLayanan> cabangLayanans = new List<CabangLayanan>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    IQueryable<CabangLayanan> cabangLayananQuery =
                        from cabangLayanan in context.CabangLayanan.Include("Layanan")
                        orderby cabangLayanan.Layanan.Nama
                        select cabangLayanan;
                    cabangLayanans = cabangLayananQuery.Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) { }
            return cabangLayanans;
        }
        private List<CabangProduk> FetchCabangProduksInternal(int page)
        {
            List<CabangProduk> cabangProduks = new List<CabangProduk>();
            try 
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    IQueryable<CabangProduk> query =
                        from cabangProduk in context.CabangProduk.Include("JenisStok")
                        orderby cabangProduk.JenisStok.Nama
                        select cabangProduk;
                    cabangProduks = query.Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) {}
            return cabangProduks;
        }
        private List<Karyawan> FetchKaryawansInternal(int page)
        {
            List<Karyawan> karyawans = new List<Karyawan>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    IQueryable<Karyawan> query =
                        from karyawan in context.Karyawan.Include("KaryawanLayanan.Layanan")
                        orderby karyawan.Nama
                        select karyawan;
                    karyawans = query.ToList().Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) { }
            return karyawans;
        }
        private List<FreeGift> FetchFreeGiftsInternal(int page)
        {
            List<FreeGift> freeGifts = new List<FreeGift>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    IQueryable<FreeGift> query =
                        from freeGift in context.FreeGift.Include("JenisStok")
                        orderby freeGift.JenisStok.Nama
                        select freeGift;
                    freeGifts = query.Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) { }
            return freeGifts;
        }
        private List<Promo> FetchPromosInternal(int page)
        {
            List<Promo> promos = new List<Promo>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                using (AnataEntities context = new AnataEntities())
                {
                    IQueryable<Promo> query =
                        from promo in context.Promo.Include("Layanan")
                        orderby promo.Nama
                        select promo;
                    promos = query.Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) { }
            return promos;
        }
        private List<JenisPembayaran> FetchJenisPembayaransInternal(int page)
        {
            List<JenisPembayaran> retval = new List<JenisPembayaran>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query =
                        from jp in context.JenisPembayaran
                        orderby jp.IsTunai, jp.Nama 
                        select jp;
                    retval = query.Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) { }
            return retval;
        }
        
        
        
        //baru
        private List<KonsumenThumbnailViewModel> FetchKonsumenTVMsInternal(int page) {
            List<KonsumenThumbnailViewModel> retval = new List<KonsumenThumbnailViewModel>();
            KonsumenThumbnailViewModel ktvm = null;
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                using (AnataEntities context = new AnataEntities())
                {
                    var query = from konsumen in context.Konsumen
                                orderby konsumen.Nama
                                select konsumen;
                    foreach (var originalK in query
                        .Skip(page * pageSize).Take(pageSize)
                        .ToList())
                    {
                        ktvm = new KonsumenThumbnailViewModel();
                        ktvm.Nama = originalK.Nama;
                        ktvm.Alamat = originalK.Alamat;
                        ktvm.Telepon = originalK.NoTelepon;
                        ktvm.JenisKelamin = originalK.JenisKelamin;
                        retval.Add(ktvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<CabangLayananThumbnailViewModel> FetchCabangLayananTVMsInternal(int page)
        {
            List<CabangLayananThumbnailViewModel> retval = new List<CabangLayananThumbnailViewModel>();
            CabangLayananThumbnailViewModel cltvm = null;
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                int idCabang = Int32.Parse(ConfigurationManager.AppSettings["IdCabang"].ToString());
                using (AnataEntities context = new AnataEntities())
                {
                    var query = from cabangLayanan in context.CabangLayanan
                                where cabangLayanan.IdCabang == idCabang
                                orderby cabangLayanan.Layanan.Nama
                                select cabangLayanan;
                    foreach (var originalCL in query
                        .Skip(page * pageSize).Take(pageSize)
                        .ToList())
                    {
                        cltvm = new CabangLayananThumbnailViewModel();
                        cltvm.IdCabang = originalCL.IdCabang;
                        cltvm.NamaCabang = originalCL.Cabang.Nama;
                        cltvm.IdLayanan = originalCL.IdLayanan;
                        cltvm.NamaLayanan = originalCL.Layanan.Nama;
                        cltvm.Harga = originalCL.HargaLayanan;
                        retval.Add(cltvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<CabangProdukThumbnailViewModel> FetchCabangProdukTVMsInternal(int page)
        {
            List<CabangProdukThumbnailViewModel> retval = new List<CabangProdukThumbnailViewModel>();
            CabangProdukThumbnailViewModel cptvm = null;
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                int idCabang = Int32.Parse(ConfigurationManager.AppSettings["IdCabang"].ToString());
                using (AnataEntities context = new AnataEntities())
                {
                    var query = from cabangProduk in context.CabangProduk
                                where cabangProduk.IdCabang == idCabang
                                orderby cabangProduk.JenisStok.Nama
                                select cabangProduk;
                    foreach (var originalCP in query
                        .Skip(page * pageSize).Take(pageSize)
                        .ToList())
                    {
                        cptvm = new CabangProdukThumbnailViewModel();
                        cptvm.IdCabang = originalCP.IdCabang;
                        cptvm.NamaCabang = originalCP.Cabang.Nama;
                        cptvm.IdJenisStok = originalCP.IdJenisStok;
                        cptvm.NamaJenisStok = originalCP.JenisStok.Nama;
                        cptvm.HargaProduk = originalCP.HargaProduk;
                        retval.Add(cptvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<KaryawanThumbnailViewModel> FetchKaryawanTVMsInternal(int page)
        {
            List<KaryawanThumbnailViewModel> retval = new List<KaryawanThumbnailViewModel>();
            KaryawanThumbnailViewModel ktvm = null;
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                using (AnataEntities context = new AnataEntities())
                {
                    var query = from karyawan in context.Karyawan
                                orderby karyawan.Nama
                                select karyawan;
                    foreach (var originalK in query
                        .Skip(page * pageSize).Take(pageSize)
                        .ToList())
                    {
                        ktvm = new KaryawanThumbnailViewModel();
                        ktvm.IdKaryawan = originalK.IdKaryawan;
                        ktvm.Nama = originalK.Nama;
                        ktvm.Alamat = originalK.Alamat;
                        ktvm.NoTelepon = originalK.NoTelepon;
                        ktvm.JenisKelamin = originalK.JenisKelamin.Nama;
                        ktvm.TanggalKeluar = originalK.TanggalKeluar;

                        KaryawanLayananThumbnailViewModel kltvm = null;
                        foreach (var originalKL in originalK.KaryawanLayanan)
                        {
                            kltvm = new KaryawanLayananThumbnailViewModel();
                            kltvm.IdKaryawan = originalKL.IdKaryawan;
                            kltvm.IdLayanan = originalKL.IdLayanan;
                            kltvm.NamaLayanan = originalKL.Layanan.Nama;
                            ktvm.KaryawanLayanans.Add(kltvm);
                        }

                        KaryawanKehadiran kehadiranTerakhir = originalK.KaryawanKehadiran
                            .Where(kk => (kk.WaktuMasuk.Value.Date == DateTime.Today) && (kk.WaktuKeluar == null))
                            .OrderByDescending(kk => kk.WaktuMasuk).FirstOrDefault();
                        if (kehadiranTerakhir != null)
                        {
                            ktvm.KehadiranTerakhir = new KaryawanKehadiranThumbnailViewModel();
                            ktvm.KehadiranTerakhir.IdKaryawanKehadiran = kehadiranTerakhir.IdKaryawanKehadiran;
                            ktvm.KehadiranTerakhir.IdKaryawan = kehadiranTerakhir.IdKaryawan;
                            ktvm.KehadiranTerakhir.NamaKaryawan = kehadiranTerakhir.Karyawan.Nama;
                            ktvm.KehadiranTerakhir.WaktuMasuk = kehadiranTerakhir.WaktuMasuk;
                            ktvm.KehadiranTerakhir.WaktuKeluar = kehadiranTerakhir.WaktuKeluar;
                        }

                        retval.Add(ktvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<FreeGiftThumbnailViewModel> FetchFreeGiftTVMsInternal(int page)
        {
            List<FreeGiftThumbnailViewModel> retval = new List<FreeGiftThumbnailViewModel>();
            FreeGiftThumbnailViewModel ftvm = null;
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                int idCabang = Int32.Parse(ConfigurationManager.AppSettings["IdCabang"].ToString());
                using (AnataEntities context = new AnataEntities())
                {
                    var query = from freeGift in context.FreeGift
                                where !freeGift.IdCabang.HasValue || freeGift.IdCabang == idCabang
                                orderby freeGift.Nama
                                select freeGift;
                    foreach (var originalF in query
                        .Skip(page * pageSize).Take(pageSize)
                        .ToList())
                    {
                        ftvm = new FreeGiftThumbnailViewModel();
                        ftvm.IdFreeGift = originalF.IdFreeGift;
                        ftvm.IdLayanan = originalF.IdLayanan;
                        ftvm.IdCabang = originalF.IdCabang;
                        ftvm.Nama = originalF.Cabang.Nama;
                        ftvm.IdJenisStok = originalF.IdJenisStok;
                        ftvm.Jumlah = originalF.Jumlah;
                        ftvm.IsAktif = originalF.IsAktif;
                        retval.Add(ftvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<PromoThumbnailViewModel> FetchPromoTVMsInternal(int page)
        {
            List<PromoThumbnailViewModel> retval = new List<PromoThumbnailViewModel>();
            PromoThumbnailViewModel ptvm = null;
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                int idCabang = Int32.Parse(ConfigurationManager.AppSettings["IdCabang"].ToString());
                using (AnataEntities context = new AnataEntities())
                {
                    var query = from promo in context.Promo
                                where !promo.IdCabang.HasValue || promo.IdCabang == idCabang
                                orderby promo.Nama
                                select promo;
                    foreach (var originalP in query
                        .Skip(page * pageSize).Take(pageSize)
                        .ToList())
                    {
                        ptvm = new PromoThumbnailViewModel();
                        ptvm.IdPromo = originalP.IdPromo;
                        ptvm.IdLayanan = originalP.IdLayanan;
                        ptvm.IdCabang = originalP.IdCabang;
                        ptvm.Nama = originalP.Cabang.Nama;
                        ptvm.IsPersentase = originalP.IsPersentase;
                        ptvm.PersentasePromo = originalP.PersentasePromo;
                        ptvm.NominalPromo = originalP.NominalPromo;
                        ptvm.Syarat = originalP.Syarat;
                        ptvm.IsOnce = originalP.IsOnce;
                        ptvm.IsDaily = originalP.IsDaily;
                        ptvm.IsWeekly = originalP.IsWeekly;
                        ptvm.IsMonthly = originalP.IsMonthly;
                        ptvm.IsYearly = originalP.IsYearly;
                        ptvm.WaktuMulai = originalP.WaktuMulai;
                        ptvm.WaktuSelesai = originalP.WaktuSelesai;
                        retval.Add(ptvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }

        private List<LayananThumbnailViewModel> FetchLayananTVMsInternal(int page)
        {
            List<LayananThumbnailViewModel> retval = new List<LayananThumbnailViewModel>();
            LayananThumbnailViewModel tempLTVM = null;
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query =
                        from l in context.Layanan
                        orderby l.Nama
                        select l;
                    foreach (var layanan in query.Skip(page * pageSize).Take(pageSize).ToList())
                    {
                        tempLTVM = new LayananThumbnailViewModel();
                        SynchLayananToLTVM(layanan, tempLTVM);
                        retval.Add(tempLTVM);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }



        //lebih baru
        private List<JenisKelamin> FetchJenisKelaminsInternal(int page)
        {
            List<JenisKelamin> retval = new List<JenisKelamin>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from jk in context.JenisKelamin
                                orderby jk.Nama
                                select jk;
                    retval = query.Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<Status> FetchStatussInternal(int page)
        {
            List<Status> retval = new List<Status>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from jk in context.Status
                                orderby jk.Nama
                                select jk;
                    retval = query.Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<Agama> FetchAgamasInternal(int page)
        {
            List<Agama> retval = new List<Agama>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from jk in context.Agama
                                orderby jk.Nama
                                select jk;
                    retval = query.Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<GolonganDarah> FetchGolonganDarahsInternal(int page)
        {
            List<GolonganDarah> retval = new List<GolonganDarah>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from jk in context.GolonganDarah
                                orderby jk.Nama
                                select jk;
                    retval = query.Skip(page * pageSize).Take(pageSize).ToList();
                }
            }
            catch (Exception) { }
            return retval;
        }

        private List<SimpleLayananViewModel> FetchLayananSVMsInternal(int page)
        {
            List<SimpleLayananViewModel> retval = new List<SimpleLayananViewModel>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from l in context.Layanan
                                orderby l.Nama
                                select l;

                    SimpleLayananViewModel slvm = null;
                    foreach (var originalL in query.Skip(page * pageSize).Take(pageSize).ToList()) {
                        slvm = new SimpleLayananViewModel();
                        slvm.Layanan = originalL;
                        retval.Add(slvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<SimpleKategoriStokViewModel> FetchKategoriStokSVMsInternal(int page)
        {
            List<SimpleKategoriStokViewModel> retval = new List<SimpleKategoriStokViewModel>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from ks in context.KategoriStok
                                orderby ks.Nama
                                select ks;

                    SimpleKategoriStokViewModel sksvm = null;
                    foreach (var originalL in query.Skip(page * pageSize).Take(pageSize).ToList())
                    {
                        sksvm = new SimpleKategoriStokViewModel();
                        sksvm.KategoriStok = originalL;
                        retval.Add(sksvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<SimpleJenisStokViewModel> FetchJenisStokSVMsInternal(int page)
        {
            List<SimpleJenisStokViewModel> retval = new List<SimpleJenisStokViewModel>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from js in context.JenisStok
                                orderby js.Nama
                                select js;

                    SimpleJenisStokViewModel sjsvm = null;
                    foreach (var originalJS in query.Skip(page * pageSize).Take(pageSize).ToList())
                    {
                        sjsvm = new SimpleJenisStokViewModel();
                        sjsvm.JenisStok = originalJS;
                        retval.Add(sjsvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<SimpleRekeningViewModel> FetchRekeningSVMsInternal(int page)
        {
            List<SimpleRekeningViewModel> retval = new List<SimpleRekeningViewModel>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from r in context.Rekening
                                orderby r.Nama
                                select r;

                    SimpleRekeningViewModel srvm = null;
                    foreach (var originalR in query.Skip(page * pageSize).Take(pageSize).ToList())
                    {
                        srvm = new SimpleRekeningViewModel();
                        srvm.Rekening = originalR;
                        retval.Add(srvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<SimpleJenisAsetViewModel> FetchJenisAsetSVMsInternal(int page)
        {
            List<SimpleJenisAsetViewModel> retval = new List<SimpleJenisAsetViewModel>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from ja in context.JenisAset
                                orderby ja.Nama
                                select ja;

                    SimpleJenisAsetViewModel sjavm = null;
                    foreach (var originalJA in query.Skip(page * pageSize).Take(pageSize).ToList())
                    {
                        sjavm = new SimpleJenisAsetViewModel();
                        sjavm.JenisAset = originalJA;
                        retval.Add(sjavm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<SimpleJenisMutasiStokViewModel> FetchJenisMutasiStokSVMsInternal(int page)
        {
            List<SimpleJenisMutasiStokViewModel> retval = new List<SimpleJenisMutasiStokViewModel>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from ja in context.JenisMutasiStok
                                orderby ja.Nama
                                select ja;

                    SimpleJenisMutasiStokViewModel sjavm = null;
                    foreach (var originalJA in query.Skip(page * pageSize).Take(pageSize).ToList())
                    {
                        sjavm = new SimpleJenisMutasiStokViewModel();
                        sjavm.JenisMutasiStok = originalJA;
                        retval.Add(sjavm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private List<SimpleJenisMutasiRekeningViewModel> FetchJenisMutasiRekeningSVMsInternal(int page)
        {
            List<SimpleJenisMutasiRekeningViewModel> retval = new List<SimpleJenisMutasiRekeningViewModel>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                AnataEntities context = new AnataEntities();
                using (context)
                {
                    var query = from jmr in context.JenisMutasiRekening
                                orderby jmr.Nama
                                select jmr;

                    SimpleJenisMutasiRekeningViewModel sjmrvm = null;
                    foreach (var originalJMR in query.Skip(page * pageSize).Take(pageSize).ToList())
                    {
                        sjmrvm = new SimpleJenisMutasiRekeningViewModel();
                        sjmrvm.JenisMutasiRekening = originalJMR;
                        retval.Add(sjmrvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        #endregion



        #region PrivateMethods.Synchronizer
        private void SynchLayananToLTVM(Layanan original, LayananThumbnailViewModel ltvm)
        {
            ltvm.IdLayanan = original.IdLayanan;
            ltvm.Nama = original.Nama;
        }
        #endregion
    }
}
